package com.bzgwl.mybatis_plus.security;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bzgwl.mybatis_plus.sys.entity.Permission;
import com.bzgwl.mybatis_plus.sys.entity.Role;
import com.bzgwl.mybatis_plus.sys.mapper.PermissionMapper;
import com.bzgwl.mybatis_plus.sys.mapper.RoleMapper;
import com.bzgwl.mybatis_plus.utils.UrlPathMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * Author: Professor_Kong
 * date: 2018/3/22
 */
@Service
@SuppressWarnings("all")
public class FilterSourceMetadataSource implements FilterInvocationSecurityMetadataSource {

    private static Map<String, Collection<ConfigAttribute>> resourceMap = null;

    @Autowired
    private PermissionMapper permissionMapper;

    @Autowired
    private RoleMapper roleMapper;

    private UrlPathMatcher pathMatcher;


    /**
     * 返回所请求资源所需要的权限
     * 针对资源的URL
     * @param object
     * @return
     * @throws IllegalArgumentException
     */
    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {

        if(resourceMap == null){
            loadResourcePermission();
        }


        Iterator<String> resourceUrls = resourceMap.keySet().iterator();
        // object getRequestUrl 是获取用户请求的url地址
        String url = ((FilterInvocation) object).getRequestUrl();

        while (resourceUrls.hasNext()) {
            String resUrl = resourceUrls.next();
            if(null == resUrl || resUrl.isEmpty()) {
                continue;
            }
            pathMatcher = new UrlPathMatcher();
            if (pathMatcher.pathMatchesUrl(url,resUrl)) {
                Collection<ConfigAttribute> configAttributes = resourceMap.get(resUrl);
                return configAttributes;
            }
        }

        return null;
    }

    /**
     * 获取所有配置权限
     * @return
     */
    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        if(resourceMap == null){
            loadResourcePermission();
        }

        Collection<Collection<ConfigAttribute>> cacs = resourceMap.values();
        Collection<ConfigAttribute> cac = new HashSet<ConfigAttribute>();
        for (Collection<ConfigAttribute> c: cacs) {
            cac.addAll(c);
        }
        return cac;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }

    /**
     * 加载资源的权限
     */
    private void loadResourcePermission() {
        resourceMap = new HashMap<String, Collection<ConfigAttribute>>();

        List<Role> roles = roleMapper.selectList( new QueryWrapper<>());
        for (Role role : roles) {

            List<Permission> functions = permissionMapper.findPermissionByRid(role.getId());
            for (Permission function : functions) {
                Collection<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();
                ConfigAttribute configAttribute = new SecurityConfig(
                        role.getName());   //此处 为   ROLE_ADMIN
                configAttributes.add(configAttribute);
                String url=function.getMenuUrl();
                if (resourceMap.containsKey(url)) {

                    Collection<ConfigAttribute> value = resourceMap.get(url); //取出这个url的权限集合
                    value.add(configAttribute);
                    resourceMap.put(url, value);
                } else {
                    Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();
                    atts.add(configAttribute);
                    resourceMap.put(url, atts);
                }
            }
        }

    }

}